package org.example.company.conponent;

import org.springframework.cloud.endpoint.event.RefreshEvent;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Mono;

import java.util.Collections;
import java.util.List;

@Component
public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
    private final RouteDefinitionWriter rootDefinitionWriter;
    private ApplicationEventPublisher publisher;

    public DynamicRouteServiceImpl(RouteDefinitionWriter rootDefinitionWriter) {
        this.rootDefinitionWriter = rootDefinitionWriter;
    }
    public String add(RouteDefinition routeDefinition){
        rootDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        this.publisher.publishEvent(new RefreshRoutesEvent(routeDefinition));
        return "success";
    }

    public String update(RouteDefinition routeDefinition){
        try {
            rootDefinitionWriter.delete(Mono.just(routeDefinition.getId()));
        }catch (Exception e){
            return "update fail, can't find this routId";
        }
        rootDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        this.publisher.publishEvent(new RefreshRoutesEvent(routeDefinition));
        return "success";
    }

    public String updateBatch(List<RouteDefinition> routeDefinitions){
        if(CollectionUtils.isEmpty(routeDefinitions)){
            return "success";
        }
        routeDefinitions.forEach(routeDefinition -> {
            rootDefinitionWriter.delete(Mono.just(routeDefinition.getId()));
        });
        routeDefinitions.forEach(routeDefinition -> {
            rootDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        });
        this.publisher.publishEvent(new RefreshRoutesEvent(this));
        return "success";
    }

    public String delete(String id){
        rootDefinitionWriter.delete(Mono.just(id));
        return "success";
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher=applicationEventPublisher;

    }
}
